package com.dhcc.core.config;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.dhcc.core.config.properties.PrimaryDataSourceProperties;
import com.dhcc.core.config.properties.SecondaryDataSourceProperties;
import com.dhcc.core.config.properties.ThirdaryDataSourceProperties;
import com.dhcc.core.framework.constant.DataSourceType;
import com.dhcc.core.framework.datasources.DynamicDataSource;

/**
 * 配置多数据源
 * 
 * @ClassName: DataSourceConfig
 * @Description: TODO
 * @author: cyf
 * @date: 2018年3月22日 上午10:45:19
 */
@Configuration
@EnableTransactionManagement(order = 2)//由于引入多数据源，所以让spring事务的aop要在多数据源切换aop的后面
public class DataSourceConfig {

    @Autowired
    PrimaryDataSourceProperties primaryDataSourceProperties;
    @Autowired
    SecondaryDataSourceProperties secondaryDataSourceProperties;
    @Autowired
    ThirdaryDataSourceProperties thirdaryDataSourceProperties;

    /**
     * 主数据源
     */
    private DruidDataSource primaryDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        primaryDataSourceProperties.config(dataSource);
        return dataSource;
    }

    /**
     * 另一个数据源
     */
    private DruidDataSource secondaryDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        secondaryDataSourceProperties.config(dataSource);
        return dataSource;
    }

    /**
     * 另一个数据源
     */
    private DruidDataSource thirdaryDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        thirdaryDataSourceProperties.config(dataSource);
        return dataSource;
    }

    /**
     * 单数据源连接池配置
     */
    @Bean
    @ConditionalOnProperty(prefix = "sys", name = "mutiDatasourceOpen", havingValue = "false")
    public DruidDataSource singleDatasource() {
        return primaryDataSource();
    }

    /**
     * 多数据源连接池配置
     */
    @Bean
    @ConditionalOnProperty(prefix = "sys", name = "mutiDatasourceOpen", havingValue = "true")
    public DynamicDataSource mutiDataSource() {

        DruidDataSource primaryDataSource = primaryDataSource();
        DruidDataSource secondaryDataSource = secondaryDataSource();
        DruidDataSource thirdaryDataSource = thirdaryDataSource();

        try {
            primaryDataSource.init();
            secondaryDataSource.init();
            thirdaryDataSource.init();
        } catch (SQLException sql) {
            sql.printStackTrace();
        }

        Map<String, DataSource> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.PRIMARY, primaryDataSource);
        targetDataSources.put(DataSourceType.SECONDARY, secondaryDataSource);
        targetDataSources.put(DataSourceType.THIRDARY, thirdaryDataSource);
        return new DynamicDataSource(primaryDataSource, targetDataSources);
    }
    /**
     * 自动识别使用的数据库类型
     * 在mapper.xml中databaseId的值就是跟这里对应，
     * 如果没有databaseId选择则说明该sql适用所有数据库
     * */
    @Bean
    public DatabaseIdProvider getDatabaseIdProvider(){
        DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
        Properties properties = new Properties();
        properties.setProperty("Oracle","oracle");
        properties.setProperty("MySQL","mysql");
        properties.setProperty("DB2","db2");
        properties.setProperty("Derby","derby");
        properties.setProperty("H2","h2");
        properties.setProperty("HSQL","hsql");
        properties.setProperty("Informix","informix");
        properties.setProperty("MS-SQL","ms-sql");
        properties.setProperty("PostgreSQL","postgresql");
        properties.setProperty("Sybase","sybase");
        properties.setProperty("Hana","hana");
        databaseIdProvider.setProperties(properties);
        return databaseIdProvider;
    }
}
